package common.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * 通过JPA操作数据库的通用DAO接口
 * 
 * @author liuxj
 * @version 1.0.0 2017-07-10
 */
public interface IBaseJpaDAO {
    /**
     * 保存新增实体
     * 
     * @param entity
     *            实体对象
     */
    void persist(Object entity);

    /**
     * 修改实体对象
     * 
     * @param entity
     *            实体对象
     */
    void merge(Object entity);

    /**
     * 删除实体
     * 
     * @param entity
     *            实体对象
     */
    void remove(Object entity);

    /**
     * 删除实体
     * 
     * @param entity
     *            实体的Class对象
     * @param id
     *            实体ID
     */
    <T> void remove(Class<T> entity, Serializable id);

    /**
     * 把对实体的修改立刻刷新到数据库中
     */
    void flush();

    /**
     * 刷新实体，得到最新数据
     * 
     * @param entity
     *            实体类型
     */
    void refresh(Object entity);

    /**
     * 根据实体ID查询实体对象
     * 
     * @param entity
     *            实体Class对象
     * @param id
     *            实体ID
     * @return entity
     */
    <T> T findById(Class<T> entity, Serializable id);

    /**
     * 查询数据库中指定实体的列表
     * 
     * @param entity
     *            实体类型
     * @return entityList
     */
    <T> List<T> findAll(Class<T> entity);

    /**
     * 根据查询条件查询实体信息列表
     * 
     * @param propertyName
     *            实体属性名
     * @param propertyValue
     *            实体属性值
     * @param isLike
     *            是否使用like查询，默认为false
     * @return entityList
     */
    <T> List<T> findByProperty(Class<T> entity, String propertyName, Object propertyValue, boolean isLike);

    /**
     * 根据查询条件查询实体信息列表，使用"="查询
     * 
     * @param propertyName
     *            实体属性名
     * @param propertyValue
     *            实体属性值
     * @return entityList
     */
    <T> List<T> findByProperty(Class<T> entity, String propertyName, Object propertyValue);

    /**
     * 根据查询条件查询单个实体信息
     * 
     * @param propertyName
     *            实体属性名
     * @param propertyValue
     *            实体属性值
     * @return entity
     */
    <T> T findUniqueByProperty(Class<T> entity, String propertyName, Object propertyValue);

    /**
     * 根据查询条件查询实体数量
     * 
     * @param propertyName
     *            实体属性名
     * @param propertyValue
     *            实体属性值
     * @param isLike
     *            是否使用like查询，默认为false
     * @return count
     */
    Long findCountByProperty(Class<?> entity, String propertyName, Object propertyValue, boolean isLike);

    /**
     * 根据查询条件查询实体数量，使用"="查询
     * 
     * @param propertyName
     *            实体属性名
     * @param propertyValue
     *            实体属性值
     * @return count
     */
    Long findCountByProperty(Class<?> entity, String propertyName, Object propertyValue);

    /**
     * 根据查询条件查询实体信息列表
     * 
     * @param entity
     *            实体类型
     * @param params
     *            实体查询参数，例如：params.put(实体属性名, 实体属性值);
     * @param isLike
     *            是否使用like查询，默认为false
     * @return entityList
     */
    <T> List<T> findByCondition(Class<T> entity, Map<String, Object> params, boolean isLike);

    /**
     * 根据查询条件查询实体信息列表，使用"="查询
     * 
     * @param entity
     *            实体类型
     * @param params
     *            实体查询参数，例如：params.put(实体属性名, 实体属性值);
     * @return entityList
     */
    <T> List<T> findByCondition(Class<T> entity, Map<String, Object> params);

    /**
     * 根据查询条件查询单个实体信息
     * 
     * @param entity
     *            实体类型
     * @param params
     *            实体查询参数，例如：params.put(实体属性名, 实体属性值);
     * @return entity
     */
    <T> T findUniqueByCondition(Class<T> entity, Map<String, Object> params);

    /**
     * 根据查询条件查询实体数量
     * 
     * @param entity
     *            实体类型
     * @param params
     *            实体查询参数，例如：params.put(实体属性名, 实体属性值);
     * @param isLike
     *            是否使用like查询，默认为false
     * @return count
     */
    Long findCountByCondition(Class<?> entity, Map<String, Object> params, boolean isLike);

    /**
     * 根据查询条件查询实体数量，使用"="查询
     * 
     * @param entity
     *            实体类型
     * @param params
     *            实体查询参数，例如：params.put(实体属性名, 实体属性值);
     * @return count
     */
    Long findCountByCondition(Class<?> entity, Map<String, Object> params);

    /**
     * 根据JPQL的where条件查询实体信息列表
     * 
     * @param entity
     *            实体类型
     * @param jpqlWhere
     *            where查询语句(不要加where关键字)，例如：and username = ?0，注意下标是从0开始的
     * @param values
     *            参数值列表
     * @return entityList
     */
    <T> List<T> findByWhere(Class<T> entity, String jpqlWhere, Object... values);

    /**
     * 根据JPQL的where条件查询单个实体信息
     * 
     * @param entity
     *            实体类型
     * @param jpqlWhere
     *            where查询语句(不要加where关键字)，例如：and username = ?0，注意下标是从0开始的
     * @param values
     *            参数值列表
     * @return entity
     */
    <T> T findUniqueByWhere(Class<T> entity, String jpqlWhere, Object... values);

    /**
     * 根据JPQL的where条件查询实体数量
     * 
     * @param entity
     *            实体类型
     * @param jpqlWhere
     *            where查询语句(不要加where关键字)，例如：and username = ?0，注意下标是从0开始的
     * @param values
     *            参数值列表
     * @return count
     */
    Long findCountByWhere(Class<?> entity, String jpqlWhere, Object... values);
}
